#include <stdexcept>
#include <iostream>

template<typename T>
class Sigleton{
    public:
        static T * Instance()
        {
            if(m_pInstance == nullptr)
            {
                m_pInstance = new T();
            }
        }
        template <typename T0>
            static T* Instance(T0 arg0)
            {
                if(m_pInstance == nullptr)
                {
                    m_pInstance = new T(arg0);
                }
            }
        template <typename T0, typename T1>
            static T* Instance(T0 arg0, T1 arg1)
            {
                if(m_pInstance == nullptr)
                {
                    m_pInstance = new T(arg0, arg1);
                }
                return m_pInstance;
            }
        static T*GetInstance()
        {
            if(m_pInstance == nullptr)
            {
                throw std::logic_error("the instance is not init, \
                        please initalize the instance first");
            }
        }

        static void DestoryInstance()
        {
            delete m_pInstance;
            m_pInstance = nullptr;
        }
    private:
        Sigleton(void); //构造函数
        virtual ~Sigleton(void); //虚析构
        Sigleton(const Sigleton&); //拷贝构造
        Sigleton& operator=(const Sigleton&); //赋值构造
        static T * m_pInstance;
};

template<class T> T* Sigleton<T>::m_pInstance = nullptr; //静态变量，也可以用模板来初始化一下


struct A{
    A(){}
};

struct B{
    B(int x):a(x) {}
    int a;
};

struct C{
    C(int x, double y):a(x), b(y){}
    int a;
    double b;
};



int main(void)
{
    Sigleton<A>::Instance();
    Sigleton<B>::Instance(1);
    Sigleton<C>::Instance(1, 1.2);

    Sigleton<A>::GetInstance();
    B * b = Sigleton<B>::GetInstance();
    std::cout << b->a << std::endl;
    C * c = Sigleton<C>::GetInstance();
    std::cout << c->a << "\t"  << c->b << std::endl;


    Sigleton<A>::DestoryInstance();
    Sigleton<B>::DestoryInstance();
    Sigleton<C>::DestoryInstance();
    return 0;
}
